/*
 * Copyright (c) 2008-2011, The KiWi Project (http://www.kiwi-project.eu)
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * - Redistributions of source code must retain the above copyright notice,
 *   this list of conditions and the following disclaimer.
 * - Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 * - Neither the name of the KiWi Project nor the names of its contributors
 *   may be used to endorse or promote products derived from this software
 *   without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

package kiwi.core.api.triplestore;

import kiwi.core.exception.KnowledgeSpaceException;
import kiwi.core.model.Constants;
import kiwi.core.model.rdf.KiWiTriple;
import kiwi.core.model.rdf.KiWiUriResource;

import java.util.List;
import java.util.Set;

/**
 * The knowledge space service offers convenience functions for working with KiWi knowledge spaces. Lowlevel
 * manipulation of knowledge spaces is offered by TripleStore.
 * <p/>
 * A knowledgespace or (other name) namedgraph represent a own graph for a separation of the whole data in the
 * triplestore. In other words: the relationship between triples and a knowledgespace is a 1 to N relationship. Every
 * triple is though the context connect to exactly one knowledgespace.
 * <p/>
 * Every knowledgespace has own access rights, triples, reasoning rules and other metadata.
 * <p/>
 * You can create knowledgespaces for user, for imported ontologies, own created content, inferred triples and
 * systemdata
 * <p/>
 * every new triple without information of a knowledgespace is connect with the context to the defaultspace
 * <p/>
 * A knowledgespace is in a hierarchical structure leaf nodes are knowledgespaces and nodes are categoryspace.
 * A categoryspace can not contain triple. Only
 * in the case of a knowledgespace as root space is it possible that a knowledgespace has not a categoryspace.
 * <p/>
 * For Example:                             CategorySpace1                  Knowledge3
 *                                          |           |
 *                                      Knowledge1  Category2
 *                                                      |
 *                                                  Knowledge2
 *
 * @author Stefan
 */
public interface KnowledgeSpaceService {

    /**
     * Type of a space which can store triples
     */
    public static String SPACE_KNOWLEDGESPACE = Constants.NS_KIWI_CORE_KNOWLEDGESPACE + "knowledgespace";

    /**
     * Type of a space which can store categorys
     */
    public static String SPACE_KIND = Constants.NS_KIWI_CORE_KNOWLEDGESPACE + "kind";


    //****************************************
    // Get spaces
    //****************************************

    /**
     * Get all Categoryspaces and Knowledgespaces stored in this system and are not deleted.
     *
     * @return new ArrayList() if the database empty and all spaces if the database is not empty
     */
    public List<KiWiUriResource> getSpaces();

    /**
     * Get spaces which has not a parent node
     *
     * @return root spaces
     */
    public List<KiWiUriResource> getRootSpaces();

    public KiWiUriResource getCategory(KiWiUriResource space);

    /**
     * Get all children of the given Categoryspace. If space null is it will return a empty List.
     *
     * @param space Category with there SubSpaces
     * @return a List of all sub spaces (type: categoryspace and/or knowledgespace)
     */
    public List<KiWiUriResource> getChildren(KiWiUriResource space);

    /**
     * Get a space (category and knowledge) with the given title
     *
     * @param title of the space
     * @return space with this title. If there is no space with the given title return this method null
     */
    public KiWiUriResource getSpaceByTitle(String title);

    /**
     * Get a space (category and knowledge) with the given uri
     *
     * @param uri of the space
     * @return space with this title. If there is no space with the given uri return this method null
     */
    public KiWiUriResource getSpaceByUri(String uri);


    /**
     * Get all CategorySpaces
     *
     * @return all categoryspaces of the database
     */
    public List<KiWiUriResource> getCategorySpaces();

    /**
     * Get the categoryspace with the given uri
     *
     * @param uri of the categoryspace
     * @return categoryspace with this uri. If there is no categoryspace with the given uri return this method null
     */
    public KiWiUriResource getCategorySpaceByUri(String uri);

    /**
     * Get the knowledgespace with the given uri
     *
     * @param uri of the categoryspace
     * @return categoryspace with this uri. If there is no categoryspace with the given uri return this method null
     */
    public KiWiUriResource getKnowledgeSpaceByUri(String uri);

    /**
     * Get the categoryspace with the given title
     *
     * @param title of the categoryspace
     * @return categoryspace with this title. If there is no categoryspace with the given title return this method null
     */
    public KiWiUriResource getCategorySpaceByTitle(String title);

    /**
     * Get all knowledgespaces stored in this KiWi system
     *
     * @return all knowledgespaces
     */
    public List<KiWiUriResource> getKnowledgeSpaces();

    /**
     * Get the Knowledgespace which is stored in this KiWi system with the given title
     *
     * @param title title of this knowledgespace
     * @return A Knowledgespace with the given title, if it give not a knowledgespace with the title then "null"
     */
    public KiWiUriResource getKnowledgeSpaceByTitle(String title);


    /**
     * Get the personal/private knowledgespace of a given user.
     *
     * @param user user with a personal/private knowledgespace
     * @return personal/private knowledgespace of the user
     * @throws KnowledgeSpaceException if user null or not persist is or
     *                                 if user has not a personal knowledgespace
     */
    public KiWiUriResource getPersonalKnowledgeSpace(KiWiUriResource user);



    //****************************************
    // Create Spaces
    //****************************************

    /**
     * Create a knowledgespace with the given title and type, if the type is a null value or
     * single space like Defaultspace it will be return a knowledgespaceexception.
     *
     * @param uri of the new knowledgespace
     * @return the new knowledgespace otherwise is it null
     * @throws KnowledgeSpaceException
     */
    public KiWiUriResource createKnowledgeSpaceByUri(String uri) throws KnowledgeSpaceException;

    /**
     * Create a knowledgespace with the given title, if the title is null, exist as categoryspace
     * or empty it will throw a KnowledgeSpaceException
     *
     * @param uri of the new categoryspace
     * @return the new categoryspace otherwise is it null
     * @throws KnowledgeSpaceException title is invalid
     */
    public KiWiUriResource createCategorySpaceByUri(String uri) throws KnowledgeSpaceException;


    /**
     * Create a knowledgespace with the given title and type, if the type is a null value or
     * single space like Defaultspace it will be return the old instance.
     *
     * @param title of the new knowledgespace
     * @return the new knowledgespace otherwise the old instance
     * @throws KnowledgeSpaceException if title null
     */
    public KiWiUriResource createKnowledgeSpace(String title) throws KnowledgeSpaceException;

    /**
     * Create a knowledgespace with the given title, if the title is null, exist as categoryspace
     * or empty it will throw a KnowledgeSpaceException
     *
     * @param title of the new categoryspace
     * @return the new categoryspace otherwise is it null
     * @throws KnowledgeSpaceException title is invalid
     */
    public KiWiUriResource createCategorySpace(String title) throws KnowledgeSpaceException;

    //****************************************
    // remove and set
    //****************************************

    /**
     * Remove a space with the given triples or ContentItems.
     * It Removes everything is connect with the space and the items in this space. If it is a Categoryspace
     * it will remove revers all children.
     *
     * @param space which is to remove
     * @throws KnowledgeSpaceException if space is a invalid value (null, empty or null title)
     */
    public void removeSpaceWithContent(KiWiUriResource space) throws KnowledgeSpaceException;

    /**
     * Move the given triples to a knowledgespace
     *
     * @param triplesToMove triple which are move to a new knowledgespace
     * @param space space which will contain the new triples
     * @throws KnowledgeSpaceException if triplesToMove or space are invalid values
     */
    public void moveContentTo(List<KiWiTriple> triplesToMove, KiWiUriResource space) throws KnowledgeSpaceException;

    /**
     * Move the given triples to a knowledgespace
     *
     * @param tripleToMove triple which are move to a new knowledgespace
     * @param space space which will contain the new triples
     * @throws KnowledgeSpaceException if triplesToMove or space are invalid values
     */
    public void moveContentTo(KiWiTriple tripleToMove, KiWiUriResource space) throws KnowledgeSpaceException;

    /**
     * Set a space for a user as a private knowledgeSpace. If user null space owner is nobody !!!
     *
     * @param user  user for the private knowledgeSpace
     * @param space title of the space which is the new private/personal knowledgespace
     * @throws KnowledgeSpaceException if user null or not persist is
     *                                 or if space has a type or user has a personal knowledgeSpace
     */
    public KiWiUriResource setPersonalKnowledgeSpace(KiWiUriResource user, KiWiUriResource space)
            throws KnowledgeSpaceException;

    /**
     * Every KnowledgeSpaceAllocation has a extra type (a RDF-Type) this Type describe the
     * use of a KnowledgeSpaceAllocation. You can set the type of a KnowledgeSpaceAllocation with
     * constants from the class KnowledgeSpaceService. Only this constants
     * are possible !!!
     *
     * @param type  Type for the given space
     * @param space space which become the given type
     * @throws KnowledgeSpaceException if type null or not valid and space not persist or null
     */
//    public void setKindOfKnowledgeSpace(KiWiResource type, KiWiUriResource space) throws KnowledgeSpaceException;


    /**
     * Every KnowledgeSpaceAllocation has a extra type (a RDF-Type) this Type describe the
     * use of a KnowledgeSpaceAllocation. You can get the kind of this type as KiWiResource
     * though the given space.
     *
     * @param space include the kind which you get with this method
     * @return kind of the given space
     */
//    public KiWiUriResource getKindOfKnowledgeSpace(KiWiUriResource space);


    //****************************************
    // get/create default, inferred
    //****************************************


    /**
     * Return the knowledge space that is currently selected for write access. The currently active knowledge space
     * is either the default knowledge space or explicitly passed as argument ctx to web service calls.
     *
     * @return a KiWiUriResource representing the current knowledge space
     */
    public KiWiUriResource getCurrentKnowledgeSpace();

    /**
     * Return the knowledge space used for storing system information.
     *
     * @return a KiWiUriResource representing the system knowledge space
     */
    public KiWiUriResource getSystemKnowledgeSpace();

    /**
     * Return the set of knowledge spaces that is currently active for reading. The set of active knowledge spaces
     * is either selected explicitly in web service calls or it consists of all knowledge spaces.
     *
     * @return a set of KiWiUriResources indicating the active knowledge spaces
     */
    public Set<KiWiUriResource> getActiveKnowledgeSpaces();

    /**
     * Get the uri of the inferred knowledgespace
     *
     * @return uri of this inferred knowledgespace
     */
    public KiWiUriResource getInferredKnowledgeSpace();

    /**
     * Get the uri of the default knowledgespace
     *
     * @return
     */
    public KiWiUriResource getDefaultKnowledgeSpace();

    //****************************************
    // update methods
    //****************************************

    /**
     * Update the title of this space
     *
     * @param item item which are updated
     * @param title new title of this item
     */
    public void updateTitle(KiWiUriResource item, String title);

    /**
     * Update the category of this space
     *
     * @param item item which are updated
     * @param category new category of this item
     */
    public void updateCategorySpace(KiWiUriResource item, KiWiUriResource category) throws KnowledgeSpaceException;

}
